use std::{mem, str::FromStr};

use uuid::Uuid;

use crate::entity::EntityId;

#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct PlayerId(Uuid);

impl PlayerId {
    pub fn from_username(s: &str) -> Self {
        let namespace = player_namespace();
        Self(Uuid::new_v5(&namespace, s.as_bytes()))
    }

    pub fn random() -> Self {
        Self(Uuid::now_v7())
    }

    pub fn inner(&self) -> &Uuid {
        &self.0
    }

    pub fn into_inner(self) -> Uuid {
        self.0
    }

    /// Returns the player ID as an entity ID.
    pub fn as_entity_id(&self) -> &EntityId {
        // SAFETY same ABI
        unsafe { mem::transmute(self) }
    }
}

// TODO convert into const
pub fn player_namespace() -> Uuid {
    Uuid::from_str("0a93cf87-3db0-4cd1-a833-ddd4cd647c3e").unwrap()
}
